package persistent.prestige.console.threadmode.t3;

import java.io.IOException;  
import java.net.InetSocketAddress;  
import java.nio.channels.ServerSocketChannel;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import persistent.prestige.console.threadmode.t3.threadpool.MyThreadFactory;
import persistent.prestige.utils.LogUtils;  
  
  
/** 
 * Reactor 主从Reactor模式实现 
 *  
 * Acceptor,其实个人认为，这里就是服务端角色 
 * @author dingwei2
 * 
 */  
public class NioServer {  
      
    private static final int DEFAULT_PORT = 9080;  
    
    //此处使用线程池，增加程序的健壮性，虽然，只启用了一个线程，但如果那个线程由于异常退出后，会新建一个线程来重新工作。
    private static ThreadPoolExecutor acceptors = newThreadPool("Nio-Acceptor");
      
    public static void main(String[] args) {  
    	acceptors.execute(new Acceptor());
    }  
      
      
    private static class Acceptor implements Runnable {  
          
        // main Reactor 线程池，用于处理客户端的连接请求  
        private static ExecutorService mainReactor = NioServer.newThreadPool("Main-Reactor");  
  
        public void run() {  
            // TODO Auto-generated method stub  
            ServerSocketChannel ssc = null;  
              
            try {  
                ssc = ServerSocketChannel.open();  
                ssc.configureBlocking(false);  
                ssc.bind(new InetSocketAddress(DEFAULT_PORT));  
                  
                //转发到 MainReactor反应堆  
                dispatch(ssc);  
                  
                LogUtils.log("服务端成功启动。。。。。。");
                  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
          
        private void dispatch(ServerSocketChannel ssc) {  
            mainReactor.submit(new MainReactor(ssc));  
        }  
          
    }  
    
    
	private static ThreadPoolExecutor newThreadPool(String threadNamePrix) {
		return new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
				new MyThreadFactory(threadNamePrix));
	}
      
  
}  